package com.zglc.ms.shop.filter;

import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.DatatypeConverter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.DefaultClaims;

/**
 * JwtHelper
 * <p>
 * </p>
 *
 * @author Vigor Yuan
 */
public class JwtHelper {

	private static Logger logger = LoggerFactory.getLogger(JwtHelper.class);

	public static String createJWT(String id, String issuer, String subject, Map<String, Object> claimsMap,
			long ttlMillis) {

		SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

		long nowMillis = System.currentTimeMillis();
		Date now = new Date(nowMillis);

		byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary("IpEVZSji7BBQpTA9DcrQ7WrJXXBd6xib");
		Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());

		JwtBuilder builder = Jwts.builder().setClaims(claimsMap).setId(id).setIssuedAt(now).setSubject(subject)
				.setIssuer(issuer).signWith(signatureAlgorithm, signingKey);

		if (ttlMillis >= 0) {
			long expMillis = nowMillis + ttlMillis;
			Date exp = new Date(expMillis);
			builder.setExpiration(exp);
		}

		return builder.compact();
	}

	public static Claims parseJWT(String jwt) {
		SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

		Key signingKey = new SecretKeySpec("IpEVZSji7BBQpTA9DcrQ7WrJXXBd6xib".getBytes(), signatureAlgorithm.getJcaName());
		try {
			Claims claims = Jwts.parser().setSigningKey(signingKey).parseClaimsJws(jwt).getBody();
			return claims;
		} catch (Exception e) {
			logger.error("parseJwt error " + e.getMessage());
		}

		Map<String, Object> claimsMap = new HashMap<>();
		Claims claims = new DefaultClaims(claimsMap);
		return claims;
	}

	public static Claims parseJWTzglc(String jwt) {
		SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

		Key signingKey = new SecretKeySpec("zglc".getBytes(), signatureAlgorithm.getJcaName());
		try {
			Claims claims = Jwts.parser().setSigningKey(signingKey).parseClaimsJws(jwt).getBody();
			return claims;
		} catch (Exception e) {
			logger.error("parseJwt error " + e.getMessage());
		}

		Map<String, Object> claimsMap = new HashMap<>();
		Claims claims = new DefaultClaims(claimsMap);
		return claims;
	}
	
	public static void main(String[] args) {
		System.out.println(parseJWT("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vc2hvcHRlc3QubGxmMzYwLmNvbS93ZWNoYXQvbm90aWZ5IiwiaWF0IjoxNDk5NzQxODM2LCJleHAiOjE4NTk3NDE4MzYsIm5iZiI6MTQ5OTc0MTgzNiwianRpIjoiTjlWVWgzaUpFeHpQaWppTyIsInN1YiI6bnVsbCwidXNlcklkIjoiMTE2MjgiLCJvcGVuSWQiOiJvR0tkczB3SE05SkJTUlc5OU9iOWpFRWw5TndjIiwidXNlclR5cGUiOjF9.wgEsGjumGP06sfNNllPvaS_opapw8MjKB8B8AN7VO-g"));
//		System.out.println(parseJWTzglc("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjExNjQzLCJvcGVuSWQiOiJvMTV6eXQ3eXl3bU5yMEJhU0dnNkUteHF6YUI0Iiwibmlja25hbWUiOiJcdTY3M2RcdTY3MjhcdTY3M2RcdTY3MjgiLCJhdmF0YXIiOiJodHRwOlwvXC93eC5xbG9nby5jblwvbW1vcGVuXC9TYXA2STVzZVlhUktrUjNzZFZka2lhc0FlNkFZd0piYzgyc215ajlaWUlOM1ZIRXNxZzdGS1YxcEZqMHdXbEdNUHhiV2lhRnJmeTJVNHd1UGhQOGQ1UDloVXRZRm1rZTNOTlwvMCIsInVzZXJUeXBlIjoxLCJwaG9uZSI6IjE4MzAxMDExOTcyIiwiZXhwIjoxNDk5Njc0ODY1fQ.kvOQw1r-C_hXza-Z9gXW3BGH9yHG_bK18yHKw8LgzNE"));
		
//		Map<String, Object> map = new HashMap <String, Object>();
//		map.put("userId", 15);
//		String key = createJWT("zglc", "zglc", "zglc", map, 100*60*60*12);
//		System.out.println(key);
//		System.out.println(parseJWT(key));
	}
	
	public static Integer getUserId(HttpServletRequest request) {
		Claims claims = (Claims) request.getAttribute("claims");
		return getUserId(claims);
	}

	public static String getOpenId(HttpServletRequest request) {
		Claims claims = (Claims) request.getAttribute("claims");
		return getOpenId(claims);
	}

	public static Integer getUserId(Claims claims) {
		if (claims == null) {
			return null;
		}
		
		Integer userId = null;
		try {
			Object userIdObj = claims.get("userId", Object.class);
			logger.info("getUserId userIdObj = " + userIdObj.toString());
			if(userIdObj instanceof String){
				userId = Integer.valueOf((String)userIdObj);
			} else if(userIdObj instanceof Integer){
				userId = (int)userIdObj;
			}
			
			
		} catch (Exception e) {
			logger.error("return e userId---------" + claims.get("userId", Object.class));
			try {
				String userIdString = claims.get("userId", String.class);
				userId = Integer.valueOf(userIdString);
			} catch (Exception e2) {
				logger.error("return e2 userId---------" + claims.get("userId", Object.class));
				userId = claims.get("userId", Integer.class);
			}
			
		}
		
		if(userId == null||userId <= 0){
			return null;
		}
		
		return userId;
	}

	public static String getOpenId(Claims claims) {
		if (claims == null) {
			return null;
		}
		
		String openId = claims.get("openId", String.class);
		if(StringUtils.isEmpty(openId)){
			return "";
		}
		
		return openId;
	}
	
	public static String getWxImgUrl(Claims claims) {
		if (claims == null) {
			return null;
		}
		
		String weixinImgUrl = claims.get("avatar", String.class);
		logger.info("getWxImgUrl weixinImgUrl " + weixinImgUrl);
		if(StringUtils.isEmpty(weixinImgUrl)){
			return "";
		}
		
		return weixinImgUrl;
	}
	
}